package algorithm.program_beauty;

import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

/**
 * @author Seon
 * @date 2023/4/9
 */
@Slf4j
public class 一的数目 {
    public static void main(String[] args) {
        StringBuilder builder = new StringBuilder();
        for (int i = 1; i <= 100000000; i++) {
            builder.append(i);
        }
        String temp = builder.toString();

        double sumTime = 0;
        int rounds = 20;
        // 测试10轮平均耗时
        for (int i = 0; i < rounds; i++) {
            long startTime = System.nanoTime();

            long l = count1InAInteger(temp, '1');
//            int l = countChar(temp, '1');
//            System.out.println("有这么多个1  " + l);

            long endTime = System.nanoTime();
            long elapsedTime = endTime - startTime;
            sumTime += (elapsedTime/1e9);
            log.info("第{}轮耗时{}s，总共耗时{}s", i+1, elapsedTime/1e9, sumTime);
        }
        System.out.println("平均耗时:" + sumTime / rounds);
    }

    /**
     * 得到一个数字中的1的个数
     * @return 1的个数
     */
    public static long count1InAInteger(String str, char ch) {
        return str.chars().parallel().filter(c -> c == ch).count();
    }


    public static int countChar(String str, char ch) {
        int count = 0;  // 计数器，用于统计指定字符出现的总次数
        int numThreads = Runtime.getRuntime().availableProcessors();  // 获取可用的CPU核心数
        ExecutorService executor = Executors.newFixedThreadPool(numThreads);  // 创建线程池
        int chunkSize = str.length() / numThreads;  // 计算每个线程处理的子串长度
        List<Future<Integer>> futures = new ArrayList<>();  // 用于存储每个线程的计数结果

        // 按照线程数进行分块处理，每个线程独立处理一段子串
        for (int i = 0; i < numThreads; i++) {
            int startIndex = i * chunkSize;  // 子串起始位置
            int endIndex = (i == numThreads - 1) ? str.length() : (i + 1) * chunkSize;  // 子串结束位置
            Future<Integer> future = executor.submit(() -> {
                int localCount = 0;  // 用于统计当前线程中指定字符的出现次数
                for (int j = startIndex; j < endIndex; j++) {
                    if (str.charAt(j) == ch) {  // 如果当前字符等于指定字符，计数器加一
                        localCount++;
                    }
                }
                return localCount;  // 返回当前线程中指定字符的出现次数
            });
            futures.add(future);  // 将当前线程的计数结果加入列表中
        }

        // 等待所有线程计算完毕，并将它们的计数结果相加
        for (Future<Integer> future : futures) {
            try {
                count += future.get();  // 获取当前线程的计数结果，并加入总计数器中
            } catch (InterruptedException | ExecutionException e) {
                e.printStackTrace();
            }
        }

        executor.shutdown();  // 关闭线程池
        return count;  // 返回总计数结果
    }
}
